home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
TARFILE.GZ
/
tarfile
/
ch_4.3
/
xah
/
ah_aoi.c
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
4KB
|
188 lines
/*
* ah_aoi.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* AH_AOI
*
* domain Area Histogram for given Area Of Interest (in binary image)
* by flooding of domains and pixel counting
*
*/
#include "xah.h"
#define F_TO_INT(x) ( ((x)-(int)(x)<0.5) ? (int)(x) : (int)(x)+1 )
#define ON 1
#define OFF 0
#define SELECT_AOI ON
#define CLR_BG ON /* clear screen, retain centroids */
#define XDIM 512
#define YDIM 512
#define WHITE_ON_BLACK 0
#define BLACK_ON_WHITE 1
#define IMG_TYPE BLACK_ON_WHITE
#define BLACK 0
#define WHITE 255
#define OFF_WHITE 254
#define OFF_BLACK 1
#define MIN_AREA 5 /* do not mark doms wt a < MIN_AREA */
#undef AOI_DEBUG
#undef DA_DEBUG
#undef S_DEBUG
/* globals */
int AREA_ONLY = 0; /* when set, use routine proc_img() */
/*
* scan domains, measure areas and construct centroids
*/
int
ah_AOI (int x1, int y1, int x2, int y2, Image * imgIn, Image * imgOut, struct bubble *cbub, int nmax)
{
int i, j;
int imin, jmin, imax, jmax;
int left_x, right_x;
int ncols, nrows;
int id, nd;
int interior_index, cur_index, new_index;
int flood_reg_index, mark_index = -1;
unsigned int cur_area;
double xc, yc;
jmin = x1;
imin = y1;
jmax = x2;
imax = y2;
left_x = jmin;
right_x = jmax - 1;
ncols = jmax - jmin;
nrows = imax - imin;
#ifdef AOI_DEBUG
printf ("\ndimensions of AOI to be scanned in bdy_AOI:\n");
printf ("...jmin = %d, imin = %d\n", jmin, imin);
printf ("...jmax = %d, imax = %d\n", jmax, imax);
printf ("\nrow limits:\n");
printf ("...left_x = %d, right_x = %d\n", left_x, right_x);
printf ("...number of cols: %d, number of rows: %d\n", ncols, nrows);
#endif
new_index = GRAY;
if (IMG_TYPE == WHITE_ON_BLACK) {
interior_index = WHITE;
flood_reg_index = WHITE;
mark_index = OFF_WHITE;
/*
* Draw a border around image to eliminate
* edge effects for line fills
*/
draw_rect (0, 0, imgIn->width - 1, imgIn->height - 1, imgIn, BLACK);
}
if (IMG_TYPE == BLACK_ON_WHITE) {
interior_index = BLACK;
flood_reg_index = BLACK;
mark_index = OFF_BLACK;
/*
* Draw a border around image to eliminate
* edge effects for line fills
*/
draw_rect (0, 0, imgIn->width - 1, imgIn->height - 1, imgIn, WHITE);
}
id = 0;
for (i = imin; i < imax; i++) {
for (j = left_x; j < right_x; j++) {
if ((cur_index = getpixel (j, i, imgIn)) == interior_index) {
if (id < nmax) {
if (AREA_ONLY == ON)
//??(cbub+id)->area = proc_img(j, i);
(cbub + id)->area = 0;
else {
cur_area = rfill (j, i, new_index, &xc, &yc, IMG_TYPE, imgIn);
if (cur_area > MIN_AREA) {
(cbub + id)->area = cur_area;
xc /= (double) (cbub + id)->area;
yc /= (double) (cbub + id)->area;
mark_centroid (xc - x1, yc - y1, WHITE, flood_reg_index, imgOut);
(cbub + id)->ctr.x = F_TO_INT (xc);
(cbub + id)->ctr.y = F_TO_INT (yc);
id++;
}
}
}
else {
printf ("\n...too many domains!! ");
printf (" ->check array dimension\n");
exit (1);
}
}
}
}
nd = id;
#ifdef DA_DEBUG
printf ("...domain areas:\n");
for (id = 0; id < nd; id++) {
printf (" %6u", (cbub + id)->area);
if ((id + 1) % 8 == 0)
printf ("\n");
}
printf ("\n");
#endif
return (nd);
}
/*
* encode bubble areas depending on their size relative to the mean
*/
void
encode_ba (double mean_a, double rmsq_a, struct bubble *b, int nd, Image * ip, int value)
{
int id;
int x, y;
int radius = 3;
for (id = 0; id < nd; id++) {
x = (b + id)->ctr.x;
y = (b + id)->ctr.y;
if ((b + id)->area >= mean_a + 0.5 * rmsq_a)
draw_up_triang (x, y, 6, ip, value);
else if ((b + id)->area < mean_a - 0.5 * rmsq_a)
draw_dn_triang (x, y, 6, ip, value);
else
draw_circle ((int) x, (int) y, (int) radius, ip, value);
}
}